// Loser_Syx is here.
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <ctime>
#include <random>
#include <map>
#include <set>
using namespace std;
#define test(x) (cout << "Test: " << (x) << '\n')
const int N = 1e5 + 19;
struct node {
	int l, r;
	bool operator < (const node &a) const {
		return r == a.r ? l > a.l : r < a.r;
	}
} t[N];
struct cars {
	double d, v, a;
} c[N];
double p[N];
int n, m, L, V;
double passed(double from, double to, double a) {
	return (from * from - to * to) / (2 * a);
}
void solve() {
	int len=0;
	scanf("%d%d%d%d", &n, &m, &L, &V);
	for (int i = 1; i <= n; ++i) scanf("%lf%lf%lf", &c[i].d, &c[i].v, &c[i].a);
	for (int i = 1; i <= m; ++i) scanf("%lf", &p[i]);
	for (int i = 1; i <= n; ++i) {
		if (c[i].v <= V && c[i].a <= 0) continue;
		if ((c[i].v >= V && c[i].a > 0) || (c[i].v > V && c[i].a >= 0)) {
			int x = lower_bound(p+1,p+1+m,c[i].d+(c[i].v==V))-p;
			if (x!=m+1) {
				t[++len]={x,m};
				// test(i);
			}
		} else {
			if (c[i].a < 0) {
				int x=lower_bound(p+1,p+1+m,c[i].d)-p;
				double P = passed(V,c[i].v,c[i].a);
				int y=lower_bound(p+1,p+1+m,c[i].d+P)-p-1;
				// if (i == 4) test(P);
				if (x<=y) {
					t[++len]={x,y};
					// test(i);
				}
			} else {
				double P = passed(V,c[i].v,c[i].a); // test(P);
				int x=upper_bound(p+1,p+1+m,c[i].d+P)-p,y=m;
				if (x<=y) {
					t[++len]={x,y};
					// test(i);
				}
			}
		}
	}
	printf("%d ",len);
	int ans=0,now=0; sort(t+1,t+1+len);
	for (int i=1;i<=len;++i) {
		if (t[i].l > now) {
			++ans;now = t[i].r;
		}
	} printf("%d\n", m-ans);
}
int main() {
	freopen("detect.in", "r", stdin);
	freopen("detect.out", "w", stdout);
	int t; scanf("%d", &t);
	while (t--) solve();
	return 0;
}
// 15:30 Accepted.
// 15:37 found detect4 completety WA.
// 16:17 Accepted.